Debounce & Throttle in React - 2


Posted by backas36 on 2022-04-05

上一篇講完了 debounce 之後,接下來是 throttle。

身為一個不完美又老的工程師,在初學的時候我看到這兩個名詞我就想逃走。

不過該面對的還是要面對,debounce 和 throttle 不做終究還是會要去面對 server 負擔過大的問題, server 負擔過大,你終究還是要面對前端互動不順的問題。

先對 debounce 和 throttle 做個總結,我們再來看 throttle 怎麼使用 react 實現:

debounce

在一段時間內只能執行 function 一次。
假設你現在正在做一台 300 毫秒內就會開始移動到你指定樓層的電梯,這時候突然進來了路人甲,你按下了開門鍵,於是開始等 300 毫秒,再上樓之前又突然進來了路人乙,於是又按下了開門鍵,重新計時 300 毫秒,這時候再進來了路人丙......。
無限循環的話你就永遠不能上樓,這就是 debounce,一直到都沒有人進來,這台電梯完美的等待完 300 毫秒過去。

throttle

固定的一段時間內呼叫 function
throttle 也稱為節流,debounce 稱防抖,我也不知道為什麼要叫防抖,但我不是很能理解防抖,但是節流聽起來比較親民,所以我才在這裡特別說明 throttle 是節流,debounce 我直接不介紹 XD:)
既然是節流、節流、節流,那就很好理解了,就是要稀釋掉執行 function 的頻率。
例如說呢,如果假日的高速公路交流道沒有實施節流的話,幾百台車子想要從台南交流道北上就北上,那這樣高速公路會多可怕?!所以通常在高峰期間會有節流措施,設置一個固定秒數的紅綠燈,固定一段時間放行,這就是 throttle 的概念。

接下來是 throttle 在 react 的應用:

第一個 input 是讓 user 輸入的欄位, Crazy Btn 是一個 click 之後就會根據 user 輸入的 input 去 fetch data 的 button。

    <>
      <div>
        <input value={inputValue} onChange={onInputValue} />
      </div>

      <div>
        <button onClick={onClickThrottle}>Crazy Btn</button>
      </div>
    </>

接下來是 onClickThrottle 和一些必要的 function:

const throttle = (fn, wait = 1000) => {
    let isWait = false ;
    return (...args) => {
      if(!isWait){
        fn(...args)
        isWait = true
        setTimeout(()=>isWait=false,wait)
      }
    }

  };
const throttleHandler = useCallback(throttle(fetchData, 3000), []);

const onClickThrottle = () => {
    throttleHandler(inputValue);
    console.log('fire onClickThrottle');
  };

button 綁定了 click 事件,按下之後觸發了 onClickThrottle => throttleHandler 帶著 user 的 input (inputValue) 執行 throttle(fetchData, 3000)

也就是當 click 下去之後會執行一次 fetchData ,可是在 3000 秒內怎麼 click 都不會再執行 fetchData。

可以再拉近一點看怎麼實作 throttle function 的,當我們執行 throttleHandler 的時候實際上是執行

(...args) => {
      if(!isWait){
        fn(...args)
        isWait = true
        setTimeout(()=>isWait=false,wait)
      }
}

isWait 一開始是 false ,所以當這個 function 被執行的時候就會是確認不是在等待時間內才可以下一步 => 之後執行一次 fn(...args),也就是 fetchData => 將等待狀態(isWait)改成 true => 把紅綠燈轉成紅燈,也就是開始計時 3000 秒,並且在 3000秒的時候把 isWait 改成 false。

這邊附上完整的 throttle in react 程式碼,
https://stackblitz.com/edit/react-a6kfhz?file=src/App.js

如果有錯誤或者是有任何問題,歡迎與我聯繫~










Related Posts

1934. Confirmation Rate

1934. Confirmation Rate

How to build CICD with Jenkins as code based on container

How to build CICD with Jenkins as code based on container

當每一個 UX 都變成了一筆交易 - redux saga

當每一個 UX 都變成了一筆交易 - redux saga


Comments